from functools import reduce
import functools

def char2num(s):
    digits={'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}
    return digits[s]

def fn(x,y):
    return x*10+y

def str2int(s):
    return reduce(lambda x,y:x*10+y,map(char2num,s))

s='13579'
n=str2int(s)
print(isinstance(n,int)) # True
print(n) # 13579

def process(s):
    slst=list(s) # 字符串是不可变对象，这里要用list
    for i in range(len(slst)):
        if i==0:
            slst[i]=slst[i].upper()
        else:
            slst[i]=slst[i].lower()
    return ''.join(slst) # 不能直接用str转，str转是直接加引号

lst=list(map(process,['BEN','playGame','abc']))
print(lst) # ['Ben', 'Playgame', 'Abc']

def str2float(s):
    # 不变
    digits={'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}
    def char2num(s):
        return digits[s]
    def fn(x,y):
        return x*10+y
    # 不变
    
    part1,part2=s.split(".")
    p1=reduce(fn,map(char2num,part1))
    p2=reduce(fn,map(char2num,part2))
    while p2>1:
        p2/=10
    return p1+p2

print(str2float('123.456')) # 123.456

def evennum(n):
    return n%2==0
lst=list(filter(evennum,range(10)))
print(lst) # [0, 2, 4, 6, 8]

def _odd_iter():
    n=1
    while True:
        n+=2
        yield n
def _not_divisible(n):
    return lambda x:x%n>0
def primes():
    yield 2
    it=_odd_iter()
    while True:
        n=next(it)
        yield n
        it = filter(_not_divisible(n),it)

for i in primes():
    if i<100:
        print(i)
    else:
        break

lst0=[36, 5, -12, 9, -21]
lst1=sorted(lst0,key=abs)
print(lst0) # [36, 5, -12, 9, -21]
print(lst1) # [5, 9, -12, -21, 36]

lst0=['ben','alice','HIT','China']
lst1=sorted(lst0) # 默认按ASCII码表顺序
print(lst1) # ['China', 'HIT', 'alice', 'ben']
lst1=sorted(lst0,key=str.lower) # 按小写排序
print(lst1) # ['alice', 'ben', 'China', 'HIT']
lst1=sorted(lst0,key=str.lower,reverse=True) # 逆序排列
print(lst1) # ['HIT', 'China', 'ben', 'alice']

lst0=[('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)]
def sort_by_score(t):
    return t[1]
lst1=sorted(lst0,key=sort_by_score,reverse=True)
print(lst1) # [('Adam', 92), ('Lisa', 88), ('Bob', 75), ('Bart', 66)]

def lazy_sum(*args):
    def cal_sum():
        sum=0
        for i in args:
            sum+=i
        return sum
    return cal_sum #  此处没有括号

f=lazy_sum(1,2,3,4,5)
result=f() #  此处有括号
print(result) # 15

def inc():
    x = 0
    def fn():
        nonlocal x
        x = x + 1
        return x
    return fn

f = inc()
print(f()) # 1
print(f()) # 2

def createCounter():
    i=1
    def counter():
        nonlocal i
        i+=1
        return i-1
    return counter

# 测试:
counterA = createCounter()
print(counterA(), counterA(), counterA(), counterA(), counterA()) # 1 2 3 4 5
counterB = createCounter()
if [counterB(), counterB(), counterB(), counterB()] == [1, 2, 3, 4]:
    print('测试通过!')
else:
    print('测试失败!')


def log(func):
    def wrapper(*args, **kw):
        print('call %s():' % func.__name__)
        return func(*args, **kw) # 此处不是定义，是调用，返回func函数执行结果
    return wrapper # 返回wrapper函数

@log
def now():
    print('2024-6-1')
    
print(now.__name__) # wrapper，实际上now = log(now)
now()

def log2(text):
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kw):
            print('%s %s():' % (text, func.__name__))
            return func(*args, **kw)
        # wrapper.__name__ = func.__name__
        return wrapper
    return decorator
@log2('execute')
def now2():
    print('2024-6-1')
print(now2.__name__) # wrapper，实际上now = log('execute')(now)
now2()

print(int('123',8)) # 8进制转10进制，83
print(int("123",16)) # 16进制转10进制，291
print(int('123',10)) # 10进制转10进制，123

int2=functools.partial(int,base=16)
print(int2('123')) # 291
print(int2('12')) # 18
print(int2("123",base=8)) # 83
print(int2("12")) # 18，配置不是永久改，还是partial的base=16

max2=functools.partial(max,10)
print(max2(1,20,9,3)) # 20
print(max2(1,8,9,3)) # 10